#include "../logs/wrtlog.h"
#include <vector>
#include <thread>
#include <chrono>

//注意：计时不能发生在创建线程之前和之后 因为创建线程也耗时
//只计算写日志的时间
void bench(const std::string &logger_name,size_t thr_count,size_t msg_count,size_t msg_len){
    //获取日志器
    wrtlog::Logger::ptr logger=wrtlog::getLogger(logger_name);
    if(logger.get()==nullptr) return;
    std::cout<<"测试日志："<<msg_count<<"条， 总大小: "<<(msg_count*msg_len)/1024<<"KB\n";
    //组织指定长度的日志消息
    std::string msg(msg_len -1,'A');//要追加换行
    //组织指定数量的线程
    std::vector<std::thread> threads;
    //总日志数量/线程数量就是每个线程要输出的日志数量
    size_t msg_per_thr =msg_count/thr_count;
    std::vector<double> costarr(thr_count);
    for(int i=0;i<thr_count;i++){
        threads.emplace_back([&,i](){
              //线程函数内部开始计时
              auto start =std::chrono::high_resolution_clock::now();
             //开始循环写日志
             for(int j=0;j<msg_per_thr;j++){
                logger->fatal("%s",msg.c_str());
             }
            //线程函数内部结束计时 
            auto end=std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost=end-start;
            costarr[i]=cost.count();
            std::cout<<"线程"<<i<<":"<<"\t输出数量:"<<msg_per_thr<<",耗时："<<cost.count()<<"s"<<std::endl;

        });//构造并插入
    }
    for(int i=0;i<thr_count;i++){
        threads[i].join();
    }
    //计算总耗时：多线程中 每个线程都会耗费时间 但是线程是并发处理 因此耗时最高的就是总耗时
    double max_cost=costarr[0];
    for(int i=0;i<thr_count;i++){
        max_cost=max_cost<costarr[i]?costarr[i]:max_cost;
    }
    size_t msg_per_sec=msg_count/max_cost;
    size_t size_per_sec=(msg_count*msg_len)/(max_cost*1024);
    //进行输出打印
    std::cout<<"\t总耗时: "<<max_cost<<"s\n";
    std::cout<<"\t每秒输出日志数量: "<<msg_per_sec<<"条\n";
    std::cout<<"\t每秒输出日志大小: "<<size_per_sec<<"KB\n";
}

void sync_bench(){
    std::unique_ptr<wrtlog::Logger::Builder> builder(new wrtlog::GlobalLoggerBuilder());
    builder->buildLoggerName("sync_logger");
    builder->buildLoggerLevel(wrtlog::LogLevel::value::WARN);
    builder->buildFormatter("%m%n");
    builder->buildLoggerType(wrtlog::Logger::Type::LOGGER_SYNC);
    builder->buildSink<wrtlog::FileSink>("./logfile/sync.log");
    builder->build();
    bench("sync_logger",3,1000000,100);
}
void async_bench(){
    std::unique_ptr<wrtlog::Logger::Builder> builder(new wrtlog::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildLoggerLevel(wrtlog::LogLevel::value::WARN);
    builder->buildFormatter("%m%n");
    //主要是考察CPU 和 内存的性能
    // builder->buildEnableUnsafeAsync();
    builder->buildLoggerType(wrtlog::Logger::Type::LOGGER_ASYNC);
    builder->buildSink<wrtlog::FileSink>("./logfile/async.log");
    builder->build();
    bench("async_logger",1,1000000,100);
}
int main()
{
    // sync_bench();
    async_bench();
    return 0;
}